#include "aerEventHandler.hpp"


namespace aer {

sf::Event *EventHandler::sEvent;
    
EventHandler::KeySet          EventHandler::sKeyDown;
EventHandler::KeySet          EventHandler::sKeyToReleased;
EventHandler::MouseButtonSet EventHandler::sMouseButtonDown;
EventHandler::MouseButtonSet EventHandler::sMouseButtonToReleased;
EventHandler::MouseMotion    EventHandler::sMouse;
EventHandler::JoystickMotion EventHandler::sJoystick;    
bool                            EventHandler::sClosed;
bool                            EventHandler::sResized;
bool                            EventHandler::sGainedFocus;
bool                            EventHandler::sLostFocus;
bool                            EventHandler::sJoystickConnected;



void EventHandler::Begin(sf::Event *pEvent)
{
  sEvent = pEvent;
  
  sKeyToReleased.clear();
  sKeyToReleased = sKeyDown; // costly ?
  
  sMouseButtonToReleased.clear();
  sMouseButtonToReleased = sMouseButtonDown;
  
  sMouse.deltaPosition = Vector2i( 0.0f, 0.0f);
  
  sClosed      = false;
  sResized     = false;
  sGainedFocus = false;
  sLostFocus   = false;
}

void EventHandler::End()
{
  sEvent = NULLPTR;
}


bool EventHandler::IsKeyPressed(const sf::Keyboard::Key key)
{
  return (sKeyDown.find(key) != sKeyDown.end()) &&
          !(sKeyToReleased.find(key) != sKeyToReleased.end());
}

bool EventHandler::IsKeyReleased(const sf::Keyboard::Key key)
{
  return !(sKeyDown.find(key) != sKeyDown.end()) &&
          (sKeyToReleased.find(key) != sKeyToReleased.end());
}

bool EventHandler::IsKeyUp(const sf::Keyboard::Key key) 
{
  return sKeyDown.find(key) == sKeyDown.end();
}

bool EventHandler::IsKeyDown(const sf::Keyboard::Key key) 
{
  return sKeyDown.find(key) != sKeyDown.end();
}


bool EventHandler::IsMouseButtonPressed(const sf::Mouse::Button button)
{
  return (sMouseButtonDown.find(button) != sMouseButtonDown.end()) &&
          !(sMouseButtonToReleased.find(button) != sMouseButtonToReleased.end());
}

bool EventHandler::IsMouseButtonReleased(const sf::Mouse::Button button)
{
  return !(sMouseButtonDown.find(button) != sMouseButtonDown.end()) &&
          (sMouseButtonToReleased.find(button) != sMouseButtonToReleased.end());
}

bool EventHandler::IsMouseButtonUp(const sf::Mouse::Button button)
{
  return sMouseButtonDown.find(button) == sMouseButtonDown.end();
}

bool EventHandler::IsMouseButtonDown(const sf::Mouse::Button button)
{
  return sMouseButtonDown.find(button) != sMouseButtonDown.end();
}


void EventHandler::HandleClose()
{
  sClosed = true;
}

void EventHandler::HandleResize()
{
  sResized = true;
}

void EventHandler::HandleFocus(bool bGainFocus)
{
  if (bGainFocus) {
    sGainedFocus = true;
  } else {
    sLostFocus = true;
  }
}

void EventHandler::HandleKeyboard(bool bKeyPressed)
{
  AER_ASSERT( sEvent != NULLPTR );
  
  const sf::Keyboard::Key key = sEvent->key.code;
    
  if (bKeyPressed) 
  {
    sKeyDown.insert( key );
  } 
  else 
  {
    //sKeyReleased.insert( key );
    
    // remove the key from KeyPressed
    KeySetIterator it = sKeyDown.find(key);
    if (it != sKeyDown.end()) {
      sKeyDown.erase( it );
    }
  }
}

void EventHandler::HandleMouseButton(bool bButtonPressed)
{
  AER_ASSERT( sEvent != NULLPTR );
  
  const sf::Mouse::Button button = sEvent->mouseButton.button;
  
  if (bButtonPressed)
  {
    sMouseButtonDown.insert( button );
  } 
  else 
  {
    sMouseButtonToReleased.insert( button );
    
    // remove the key from MouseButtonPressed
    MouseButtonIterator it = sMouseButtonDown.find(button);
    if (it != sMouseButtonDown.end()) {
      sMouseButtonDown.erase( it );
    }
  }
}

void EventHandler::HandleMouseMoved()
{
  AER_ASSERT( sEvent != NULLPTR );
  
  sMouse.prevPosition  = sMouse.currPosition;
  sMouse.currPosition  = Vector2i( sEvent->mouseMove.x, sEvent->mouseMove.y);
  sMouse.deltaPosition = sMouse.currPosition - sMouse.prevPosition;
}

void EventHandler::HandleJoystickMoved()
{
  AER_ASSERT( sEvent != NULLPTR );
  
  // Don't handle more than one joystick Id yet
  if (sEvent->joystickMove.joystickId > 0) {
    return;
  }
  
  int axis = sEvent->joystickMove.axis;  
  if (axis >= 4) {
    return;
  }
  
  sJoystick.position[axis] = 0.01f * sEvent->joystickMove.position;
}


void EventHandler::HandleJoystickConnected(bool state)
{
  sJoystickConnected = state;//
}

  
} // aer
